﻿using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace YArchitech.LIB.YJKControls.HYListView
{
	public class HYListView : ListView
	{
		[DllImport("user32.dll")]
		private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wPar, IntPtr lPar);

		public HYListView()
		{
			this.InitializeComponent();
			base.OwnerDraw = true;
			base.FullRowSelect = true;
			base.View = Autodesk.Revit.DB.View.Details;
			base.MultiSelect = false;
		}

		protected override void OnDrawSubItem(DrawListViewSubItemEventArgs e)
		{
			base.OnDrawSubItem(e);
		}

		protected override void OnDrawItem(DrawListViewItemEventArgs e)
		{
			base.OnDrawItem(e);
			e.DrawDefault = true;
		}

		protected override void OnDrawColumnHeader(DrawListViewColumnHeaderEventArgs e)
		{
			base.OnDrawColumnHeader(e);
			e.DrawDefault = true;
		}

		public void AddControlToSubItem(int col, int row, HYListViewButtonCell subitem, DockStyle Dock)
		{
			if (col >= base.Columns.Count || row >= base.Items.Count)
			{
				throw new ArgumentOutOfRangeException();
			}
			HYListView.EmbeddedControl embeddedControl;
			embeddedControl.Control = subitem.Btn;
			embeddedControl.Column = col;
			embeddedControl.Row = row;
			embeddedControl.Dock = Dock;
			embeddedControl.Item = base.Items[row];
			this.embeddedControls.Add(embeddedControl);
			subitem.Btn.Bounds = subitem.Bounds;
			base.Controls.Add(subitem.Btn);
		}

		public void AddControlToSubItem(int col, int row, HYListViewLabelCell subitem, DockStyle Dock)
		{
			if (col >= base.Columns.Count || row >= base.Items.Count)
			{
				throw new ArgumentOutOfRangeException();
			}
			HYListView.EmbeddedControl embeddedControl;
			embeddedControl.Control = subitem.Lbl;
			embeddedControl.Column = col;
			embeddedControl.Row = row;
			embeddedControl.Dock = Dock;
			embeddedControl.Item = base.Items[row];
			this.embeddedControls.Add(embeddedControl);
			subitem.Lbl.Bounds = subitem.Bounds;
			base.Controls.Add(subitem.Lbl);
		}

		protected int[] GetColumnOrder()
		{
			IntPtr intPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int)) * base.Columns.Count);
			if (HYListView.SendMessage(base.Handle, 4155, new IntPtr(base.Columns.Count), intPtr).ToInt32() == 0)
			{
				Marshal.FreeHGlobal(intPtr);
				return null;
			}
			int[] array = new int[base.Columns.Count];
			Marshal.Copy(intPtr, array, 0, base.Columns.Count);
			Marshal.FreeHGlobal(intPtr);
			return array;
		}

		protected System.Drawing.Rectangle GetSubItemBounds(ListViewItem Item, int SubItem)
		{
			System.Drawing.Rectangle empty = System.Drawing.Rectangle.Empty;
			if (Item == null)
			{
				throw new System.ArgumentNullException("Item");
			}
			int[] columnOrder = this.GetColumnOrder();
			if (columnOrder == null)
			{
				return empty;
			}
			if (SubItem >= columnOrder.Length)
			{
				throw new IndexOutOfRangeException("SubItem " + SubItem + " out of range");
			}
			System.Drawing.Rectangle bounds = Item.GetBounds(ItemBoundsPortion.Entire);
			int num = bounds.Left;
			int i;
			for (i = 0; i < columnOrder.Length; i++)
			{
				ColumnHeader columnHeader = base.Columns[columnOrder[i]];
				if (columnHeader.Index == SubItem)
				{
					break;
				}
				num += columnHeader.Width;
			}
			empty = new System.Drawing.Rectangle(num, bounds.Top, base.Columns[columnOrder[i]].Width, bounds.Height);
			return empty;
		}

		protected override void WndProc(ref Message m)
		{
			int msg = m.Msg;
			if (msg == 15 && base.View == Autodesk.Revit.DB.View.Details)
			{
				foreach (object obj in this.embeddedControls)
				{
					HYListView.EmbeddedControl embeddedControl = (HYListView.EmbeddedControl)obj;
					System.Drawing.Rectangle subItemBounds = this.GetSubItemBounds(embeddedControl.Item, embeddedControl.Column);
					if (base.HeaderStyle != ColumnHeaderStyle.None && subItemBounds.Top < this.Font.Height)
					{
						embeddedControl.Control.Visible = false;
					}
					else
					{
						embeddedControl.Control.Visible = true;
						switch (embeddedControl.Dock)
						{
						case DockStyle.None:
							subItemBounds.Size = embeddedControl.Control.Size;
							break;
						case DockStyle.Top:
							subItemBounds.Height = embeddedControl.Control.Height;
							break;
						case DockStyle.Bottom:
							subItemBounds.Offset(0, subItemBounds.Height - embeddedControl.Control.Height);
							subItemBounds.Height = embeddedControl.Control.Height;
							break;
						case DockStyle.Left:
							subItemBounds.Width = embeddedControl.Control.Width;
							break;
						case DockStyle.Right:
							subItemBounds.Offset(subItemBounds.Width - embeddedControl.Control.Width, 0);
							subItemBounds.Width = embeddedControl.Control.Width;
							break;
						}
						embeddedControl.Control.Bounds = subItemBounds;
					}
				}
			}
			base.WndProc(ref m);
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing && this.components != null)
			{
				this.components.Dispose();
			}
			base.Dispose(disposing);
		}

		private void InitializeComponent()
		{
			this.components = new Container();
		}

		private const int LVM_FIRST = 4096;

		private const int LVM_GETCOLUMNORDERARRAY = 4155;

		private const int WM_PAINT = 15;

		private ArrayList embeddedControls = new ArrayList();

		private IContainer components;

		private struct EmbeddedControl
		{
			public System.Windows.Forms.Control Control;

			public int Column;

			public int Row;

			public DockStyle Dock;

			public ListViewItem Item;
		}
	}
}
